//
//  ViewController.m
//  JK_const_define_static_extern
//
//  Created by 王冲 on 2019/2/4.
//  Copyright © 2019年 JK科技有限公司. All rights reserved.
//

#import "ViewController.h"
#import "TestViewController.h"
#define JKString  @"Hello world"

int const x = 20;

static int b = 20;

// 域名
NSString * const base_url =  @"http://www.baodu.com/";

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
    // 1、const测试
    // [self constTest];
    // 2、const 的使用场景
    // [self constTest2];
    // 3、const 的使用场景
    // [self staticTest];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    TestViewController *testViewController = [TestViewController new];
    [self presentViewController:testViewController animated:YES completion:nil];

    // [self staticTest];
}

#pragma mark 4、extern简单使用
-(void)externTest{
    
    /**
     
     extern
           1、声明外部全局变量，注意：extern 只能用于声明，不能用于定义
           2、工作原理：先会去当前文件下查找有没有对应全局变量，如果没有，才会去其他文件查找
     */
}

#pragma mark 3、static简单使用
-(void)staticTest{
    
    /**
     static：1.修饰局部变量，被static修饰局部变量，延长生命周期，跟整个应用程序有关
             * 被static修饰局部变量，只会分配一次内存
             * 被static修饰局部变量什么时候分配内存？程序一运行就会给static修饰变量分配内存
             2.修饰全局变量，被static修饰全局变量，作用域会修改，只能在当前文件下使用
     */
    
    static int a = 0;
    ++a;
    NSLog(@"a = %d a的内存地址=%p",a,&a);
    
}

#pragma mark 2、const 的使用场景
-(void)constTest2{
    
    [self test:@"你好！"];
    int p = 1;
    [self test1:&p];
    [self test2:2];
}

// 当一个方法的参数，只读.
-(void)test:(NSString * const)string{
    // 这句代码是报错的，被 const 修饰过后，string 是无法被修改的
    // string = @"234";
}
// 指针只读,不能通过指针修改值
- (void)test1:(int const *)a{
    //  *a = 11;
}

// 基本数据类型只读
- (void)test2:(int const)a{
    
}


#pragma mark 1、const测试
-(void)constTest{
    
    NSString *string1 = JKString;
    NSString *string2 = JKString;
    
    NSLog(@"\n%p %p",string1,string2);
    
    // 定义变量
    int a = 10;
    // 允许修改值
    a = 12;
    
    NSLog(@"a=%d",a);
    
    // const 用法一 (修饰基本变量p)
    // 这两种写法是一样的，const只修饰右边的基本变量b
    //const int b = 20; // b:只读变量
    int const b = 20; // b:只读变量
    
    // 修饰指针变量 *p，带 * 的变量，就是指针变量
    // 定义一个指向int类型的指针变量，指向a的地址
    a = 12;
    int *p = &a;
    int c = 8;
    p = &c;
    NSLog(@"p=%d",*p);
    
    // 由于p没有被修饰，它访问内存空间的值和指向的地址都可以被修改允许修改
    *p = 11;
    NSLog(@"p=%d",*p);
    
    int const *w = 7;
    const int *q = 7;
    int * const x = 7;
    const int *y = 7;
    
    int const * const h = 7;
    const int * const i = 7;
    const int * const j = 7;
    const int * const k = 7;
    
    
    
}





@end
